package com.saris.primego.common.utils;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import com.saris.primego.common.properties.LSkyProperties;
import com.saris.primego.common.result.httpRespone.*;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.*;
import java.io.File;
import java.util.concurrent.TimeUnit;

@Component
public class LSkyProUtil {
    private String token;
    private final HttpClient httpClient;
    final LSkyProperties properties;

    // 使用系统临时目录而不是Tomcat工作目录
    private static final String TEMP_DIR = System.getProperty("java.io.tmpdir") + "/lsky-uploads/";

    static {
        // 确保临时目录存在
        new File(TEMP_DIR).mkdirs();
    }

    public LSkyProUtil(LSkyProperties properties) {
        this.properties = properties;
        this.httpClient = HttpClient.newBuilder()
                .build();
        // 初始化时尝试获取Token
        refreshToken();
    }


    // ---------- Token 管理 ----------

    /**
     * 刷新Token
     *
     * @return 是否成功
     */
    private boolean refreshToken() {
        try {
            Map<String, String> credentials = new HashMap<>();
            credentials.put("email", properties.getEmail());
            credentials.put("password", properties.getPassword());

            HttpRequest request = HttpRequest.newBuilder()
                    .uri(URI.create(getBaseUrl() + "tokens"))
                    .header("Content-Type", "application/json")
                    .header("Accept", "application/json")
                    .POST(HttpRequest.BodyPublishers.ofString(JSON.toJSONString(credentials)))
                    .build();

            HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
            ApiResponse<TokenResponse> tokenResponse = parseResponse(response, new TypeReference<>() {
            });

            if (tokenResponse.isStatus() && tokenResponse.getData() != null) {
                this.token = tokenResponse.getData().getToken();
                return true;
            }
            return false;
        } catch (Exception e) {
            throw new RuntimeException("Token刷新失败: " + e.getMessage(), e);
        }
    }

    private void ensureTokenValid() {
        if (token == null) {
            if (!refreshToken()) {
                throw new RuntimeException("Token已过期且刷新失败");
            }
        }
    }

    /**
     * 上传图片
     *
     * @return 图片URL
     */
    public String uploadImage(MultipartFile file) {
        ensureTokenValid();

        // 创建唯一文件名避免冲突
        String tempFileName = "lsky_" + System.currentTimeMillis() + "_" + Objects.requireNonNull(file.getOriginalFilename()).replaceAll("[^a-zA-Z0-9\\.]", "_");

        Path tempPath = Path.of(TEMP_DIR, tempFileName);

        try {

            // 使用Files.copy确保原子操作
            Files.copy(file.getInputStream(), tempPath, StandardCopyOption.REPLACE_EXISTING);

            // 验证文件确实存在
            if (!Files.exists(tempPath)) {
                throw new IOException("临时文件创建失败: " + tempPath);
            }


            try (CloseableHttpClient httpClient = createHttpClient()) {


                // 一次性读取文件内容到字节数组
                byte[] fileBytes = file.getBytes();

                // 创建POST请求
                HttpPost httpPost = new HttpPost(getBaseUrl() + "upload");

                // 添加Token认证头
                httpPost.setHeader("Authorization", "Bearer " + this.token);

                // 构建multipart/form-data请求体
                MultipartEntityBuilder builder = MultipartEntityBuilder.create();
                builder.addBinaryBody(
                        "file",
                        tempPath.toFile(),// 使用字节数组输入流
                        ContentType.MULTIPART_FORM_DATA,
                        file.getOriginalFilename()
                );

                // 设置请求体
                HttpEntity multipartEntity = builder.build();
                httpPost.setEntity(multipartEntity);

                // 执行请求
                String respone = "";
                try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                    HttpEntity responseEntity = response.getEntity();
                    if (responseEntity != null) {
                        respone = EntityUtils.toString(responseEntity);
                    }
                }
                ApiResponse<ImageResponse> imageResponse = JSON.parseObject(respone, new TypeReference<>() {
                });
                if (imageResponse.isStatus() && imageResponse.getData() != null) {
                    String url = imageResponse.getData().getLinks().getUrl();
                    //todo:返回地址为内网ip的问题待解决。
                    return url.replace("http://192.168.101.38","http://222.187.86.6");
                }

            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            // 确保删除临时文件
            try {
                if (Files.exists(tempPath)) {
                    Files.delete(tempPath);
                }
            } catch (IOException e) {
                // 记录日志但不要抛出异常
                System.err.println("无法删除临时文件: " + tempPath + ", 原因: " + e.getMessage());
            }
        }
        return null;
    }

    public static CloseableHttpClient createHttpClient() {
        try {

            // 请求配置
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectTimeout(15000)
                    .setSocketTimeout(30000)
                    .setConnectionRequestTimeout(10000)
                    .build();

            return HttpClients.custom()
                    .setDefaultRequestConfig(requestConfig)
                    .setMaxConnTotal(50)
                    .setMaxConnPerRoute(20)
                    .setConnectionTimeToLive(30, TimeUnit.SECONDS)
                    .disableCookieManagement()
                    .disableAutomaticRetries()  // 关键：禁用自动重试
                    .disableAuthCaching()
                    .build();
        } catch (Exception e) {
            // 返回默认客户端
            return HttpClients.createDefault();
        }
    }

    //获取带"/"结尾的BaseUrl
    private String getBaseUrl() {
        return properties.getBaseUrl().endsWith("/") ? properties.getBaseUrl() + "api/v1/" : properties.getBaseUrl() + "/api/v1/";
    }


    // ---------- 辅助方法 ----------
    private <T> T parseResponse(HttpResponse<String> response, TypeReference<T> typeRef) {
        try {
            return JSON.parseObject(response.body(), typeRef);
        } catch (Exception e) {
            throw new RuntimeException("解析响应失败: " + e.getMessage() + "\n原始响应: " + response.body(), e);
        }
    }
}
